<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="test">尚硅谷IT教育</div>

<div id="demo">
  <ul>
    <li>test1</li>
    <li>test2</li>
    <li>test3</li>
  </ul>
</div>



<!--
1. [].slice.call(lis): 将伪数组转换为真数组
2. node.nodeType: 得到节点类型
3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
6. DocumentFragment: 文档碎片(高效批量更新多个节点)
-->

<script type="text/javascript">
  // 1. Array.prototype.slice.call(lis): 将伪数组转换为真数组 
  const lis = document.getElementsByTagName('li') // 伪数组
  const lis2 = Array.from(lis)
  console.log(lis, lis2)
  const lis3 = Array.prototype.slice.call(lis)
  console.log(lis3)

  // 2. node.nodeType: 得到节点类型
  // document / element / Attr / Text  <div id="test">尚硅谷IT教育</div>
  const elementNode = document.getElementById('test')
  const attrNode = elementNode.getAttributeNode('id')
  const textNode = elementNode.firstChild
  console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType)

  // Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
  const p = {
    firstName: 'A',
    lastName: 'B'
  }
  Object.defineProperty(p, 'fullName', { // 配置对象 ==> 属性描述符
    configurable: false,  // 是否可以重新define
    enumerable: false, // 是否可以枚举(for..in / keys())
    // value: 'A-B', // 指定初始值
    // writable: false,  value是否可以修改
    get () { // 回调函数, 用来得到当前属性值
      console.log('get')
      return this.firstName + '-' + this.lastName
    }, 
    set (value){ // 回调函数, 用来监视当前属性值的变化
      const names = value.split('-')
      this.firstName = names[0]
      this.lastName = names[1]
    } 
  })
  console.log(p.fullName)  // A-B
  p.firstName = 'C'
  p.lastName = 'D'
  console.log(p.fullName) //  C-D
  p.fullName = 'E-F'
  console.log(p.firstName, p.lastName) //  E F

  // 4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
  Object.keys(p).forEach(key => {
    console.log(key, p[key])
  })

  // 5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
  console.log(p.fullName, p.toString) 
  console.log(p.hasOwnProperty('fullName'), p.hasOwnProperty('toString')) // true false

  // DocumentFragment: 文档碎片(高效批量更新多个节点)
  /* 
  <div id="demo">
     <ul>
      <li>test1</li>
      <li>test2</li>
      <li>test3</li>
    </ul>
  </div>
  */
  // 创建fragment容器对象
  const fragment = document.createDocumentFragment()
  const div = document.getElementById('demo')
  let child
  while(child = div.firstChild) {
    fragment.appendChild(child) // 将child从div中移除保存到fragment中
  }

  // 只在内存中更新节点
  const lis5 = Array.prototype.slice.call(fragment.children[0].children)
  lis5.forEach(li => {
    li.textContent = 'atguigu'  // 不会更新界面
  })

  div.appendChild(fragment)  // 更新界面

</script>
</body>
</html>